home *** CD-ROM | disk | FTP | other *** search
- /*
- * utility to adjust _stksize in gcc-cc1.ttp
- *
- * Usage: fixstk size [<filename>]
- * size: specified as # of bytes nnn
- * specified as # of Kilo Bytes nnnK
- * specified as # of Mega Bytes nnnM
- * filename:
- * optional, defaults to \.gcc-cc1.ttp
- *
- * ++jrb
- *
- * modified to allow fixing applications for which size of a stack
- * is defined via _initial_stack -- mj
- */
-
- #include <stdio.h>
-
- #ifdef CROSSATARI
- #include "cross-inc/st-out.h"
- #else
- #include <st-out.h>
- #endif
-
- #if __STDC__
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #else
- #include <string.h>
- extern char *malloc();
- extern long lseek();
- #define size_t unsigned long
- #endif
-
- #ifndef FILENAME_MAX
- # define FILENAME_MAX 128
- #endif
-
- #ifdef WORD_ALIGNED
- # define SIZEOF_AEXEC ((2*sizeof(short)) + (6*sizeof(long)))
- # ifndef SYMLEN
- # define SYMLEN 8
- # endif
- # define SIZEOF_ASYM ((SYMLEN*sizeof(char)) + sizeof(short) + sizeof(long))
- # define SYM_OFFSET (sizeof(short) + (3*sizeof(long)))
- #endif
-
- #ifdef BYTE_SWAP
-
- #define SWAP4(y) (((unsigned)(y)>>24) + (((unsigned)(y)>>8)&0xff00) + \
- (((unsigned)(y)<<8)&0xff0000) + ((unsigned)(y)<<24))
- #define SWAP2(y) ((((unsigned)(y)&0xff00)>>8) + (((unsigned)(y)&0x00ff)<<8))
-
- #endif /* BYTE_SWAP */
-
- extern void dump_version(char *prog);
- char *progname = "fixstk";
-
- int error = 0;
- long newstksize;
-
- static char *sym_names[] = { "__stksize", "__initial_stack" };
-
- long find_offset (fd, fn, what)
- int fd;
- char *fn;
- int *what;
- {
- struct aexec head;
- struct asym sym;
- int all = 0;
- int index = 1;
- #ifndef WORD_ALIGNED
- char extension[sizeof (struct asym)];
- #else
- char extension[SIZEOF_ASYM];
- #endif
-
- #ifndef WORD_ALIGNED
- if(read(fd, &head, sizeof(head)) != sizeof(head))
- #else
- if(read_head(fd, &head))
- #endif
- {
- perror(fn);
- return -1;
- }
- #ifdef BYTE_SWAP
- head.a_magic = SWAP2(head.a_magic);
- head.a_syms = SWAP4(head.a_syms);
- head.a_text = SWAP4(head.a_text);
- head.a_data = SWAP4(head.a_data);
- #endif
- if(head.a_magic != CMAGIC)
- {
- fprintf(stderr,"%s: invalid magic number %x\n", fn, head.a_magic);
- return -1;
- }
- if(head.a_syms == 0)
- {
- fprintf(stderr,"%s: no symbol table\n", fn);
- return -1;
- }
- if(lseek(fd, head.a_text+head.a_data, 1) !=
- #ifndef WORD_ALIGNED
- (head.a_text+head.a_data+sizeof(head)))
- #else
- (head.a_text+head.a_data+SIZEOF_AEXEC))
- #endif
- {
- perror(fn);
- return -1;
- }
- for(;;)
- {
- #ifndef WORD_ALIGNED
- if(index && (read(fd, &sym, sizeof(sym)) != sizeof(sym)))
- #else
- if(index && read_sym(fd, &sym))
- #endif
- {
- fprintf(stderr, "%s: symbol _stksize not found\n", fn);
- return -1;
- }
- #ifdef BYTE_SWAP
- sym.a_type = SWAP2(sym.a_type);
- sym.a_value = SWAP4(sym.a_value);
- #endif
- if (index && (sym.a_type & A_LNAM) == A_LNAM)
- if (read (fd, extension, sizeof (extension)) != sizeof (extension))
- {
- fprintf (stderr, "%s: symbol _stksize not found\n", fn);
- return -1;
- }
- /* after symbol read check first for _stksize */
- index ^= 1;
- if (strncmp(sym_names[index], sym.a_name, 8) == 0)
- {
- if ((sym.a_type & A_LNAM) == A_LNAM
- && strncmp (sym_names[index] + 8, extension, sizeof (extension)))
- continue;
- if (sym.a_type & A_DATA)
- break;
- if (all++)
- {
- fprintf (stderr, "%s: symbol _stksize is undefined\n", fn);
- return -1;
- }
- }
- }
-
- *what = index;
- #ifndef WORD_ALIGNED
- return sym.a_value + sizeof(head);
- #else
- return sym.a_value + SIZEOF_AEXEC;
- #endif
- }
-
- long calc_newsize(s)
- char *s;
- {
- size_t len = strlen(s) - 1;
- long mul = 1;
- long atol();
-
- switch(s[len])
- {
- case 'k': case 'K':
- mul = 1L << 10;
- break;
- case 'm': case 'M':
- mul = 1L << 20;
- break;
- default:
- len += 1;
- }
-
- s[len] = '\0';
- return mul * atol(s);
- }
-
- int main(argc, argv)
- int argc;
- char **argv;
- {
- if (argv[0][0] != '\0')
- progname = argv[0];
-
- if (argc == 2 && strcmp(argv[1], "-v") == 0)
- {
- dump_version(progname);
- exit(0);
- }
-
- if (argc < 3)
- {
- fprintf (stderr, "Usage: %s size file...\n", progname);
- exit (1);
- }
- newstksize = calc_newsize (*++argv);
- --argc;
- while (--argc)
- error |= fix_stack (*++argv);
- exit (error);
- }
-
- int
- fix_stack (fn)
- char *fn;
- {
- int fd;
- int what;
- long stksize, offset;
-
- if((fd = open(fn, 2)) < 0)
- {
- perror(fn);
- return 1;
- }
-
- offset = find_offset(fd, fn, &what);
- if (offset < 0)
- {
- close (fd);
- return 1;
- }
-
- if(lseek(fd, offset, 0) != offset)
- {
- perror(fn);
- close(fd);
- return 1;
- }
- read(fd, &stksize, sizeof(long));
- #ifdef BYTE_SWAP
- stksize = SWAP4(stksize);
- #endif
- printf("%s: %s was %ld (%dK)\n",
- fn, sym_names[what] + 1, stksize, (int)(stksize/1024));
-
- lseek(fd, -((long)sizeof(long)), 1);
-
- #ifdef BYTE_SWAP
- newstksize = SWAP4(newstksize);
- #endif
- if(write(fd, &newstksize, sizeof(long)) != sizeof(long))
- {
- perror(fn);
- close(fd);
- return 1;
- }
-
- lseek(fd, -((long)sizeof(long)), 1);
-
- read(fd, &stksize, sizeof(long));
- #ifdef BYTE_SWAP
- stksize = SWAP4(stksize);
- #endif
- printf("%s: %s now is %ld (%dK)\n",
- fn, sym_names[what] + 1, stksize, (int)(stksize/1024));
- return close(fd) != 0;
- }
-
- #ifdef WORD_ALIGNED
- #ifndef atarist
- # define lread read
- # define lwrite write
- #endif
-
- /*
- * read header -- return !0 on err
- */
- #define ck_read(fd, addr, siz) \
- if((long)siz != lread(fd, addr, (long)siz)) return !0;
-
- int read_head (fd, a)
- int fd;
- struct aexec *a;
- {
- ck_read(fd, &a->a_magic, sizeof(a->a_magic));
- ck_read(fd, &a->a_text, sizeof(a->a_text));
- ck_read(fd, &a->a_data, sizeof(a->a_data));
- ck_read(fd, &a->a_bss, sizeof(a->a_bss));
- ck_read(fd, &a->a_syms, sizeof(a->a_syms));
- ck_read(fd, &a->a_AZero1, sizeof(a->a_AZero1));
- ck_read(fd, &a->a_AZero2, sizeof(a->a_AZero2));
- ck_read(fd, &a->a_isreloc, sizeof(a->a_isreloc));
- return 0;
- }
-
- int read_sym(fd, s)
- int fd;
- struct asym *s;
- {
- ck_read(fd, s->a_name, 8);
- ck_read(fd, &(s->a_type), sizeof(short));
- ck_read(fd, &(s->a_value), sizeof(long));
- return 0;
- }
- #endif
-